#include <string.h>
#include "driver/spi_master.h"

#include "esp_log.h"
#include "lcd_init.h"
#include "lcd_spi.h"
#include "lcd_support.h"
#include "lcd_def.h"

/* SPI句柄 */
#define LCD_SPI_HANDLE_USE SPI2_HOST

/**
 * @brief       液晶进入休眠
 * @param       无
 * @retval      无
 */
void LCD_Enter_Sleep(void)
{
    LCD_WR_REG(0x28);
    vTaskDelay(120 / portTICK_PERIOD_MS);
    LCD_WR_REG(0x10);
    vTaskDelay(50 / portTICK_PERIOD_MS);
}

/**
 * @brief       液晶退出休眠
 * @param       无
 * @retval      无
 */
void LCD_Exit_Sleep(void)
{
    LCD_WR_REG(0x11);
    vTaskDelay(120 / portTICK_PERIOD_MS);
    LCD_WR_REG(0x29);
}

#if 0
int lcd_init(int lcd_w, int lcd_h)
{
    lcd_basic_io_init();
    /* 初始化SPI总线 */
    lcd_spi_init(LCD_SPI_HANDLE_USE, lcd_w*lcd_h*2);

    lcd_set_rst(1);
    vTaskDelay(50 / portTICK_PERIOD_MS);
    lcd_set_rst(0);
    vTaskDelay(50 / portTICK_PERIOD_MS);
    lcd_set_rst(1);
    vTaskDelay(120 / portTICK_PERIOD_MS);

    LCD_WR_REG(0x11);   
    vTaskDelay(120 / portTICK_PERIOD_MS);

    LCD_WR_REG(0xff);
    LCD_WR_Byte(0xa5);
    LCD_WR_REG(0x9a);
    LCD_WR_Byte(0x08);
    LCD_WR_REG(0x9b);
    LCD_WR_Byte(0x08);
    LCD_WR_REG(0x9c);
    LCD_WR_Byte(0xb0);
    LCD_WR_REG(0x9d);
    LCD_WR_Byte(0x17);
    LCD_WR_REG(0x9e);
    LCD_WR_Byte(0xc2);
    LCD_WR_REG(0x8f);
    LCD_WR_Byte(0x22);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0x84);
    LCD_WR_Byte(0x90);
    LCD_WR_REG(0x83);
    LCD_WR_Byte(0x7B);
    LCD_WR_REG(0x85);
    LCD_WR_Byte(0x4F);
    ////GAMMA---------------------------------/////////////
    //V0[3:0]
    LCD_WR_REG(0x6e);
    LCD_WR_Byte(0x0f);
    LCD_WR_REG(0x7e);
    LCD_WR_Byte(0x0f);

    //V63[3:0]
    LCD_WR_REG(0x60);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x70);
    LCD_WR_Byte(0x00);
    //V1[5:0] 
    LCD_WR_REG(0x6d);
    LCD_WR_Byte(0x39);
    LCD_WR_REG(0x7d);
    LCD_WR_Byte(0x31);
    //V62[5:0]
    LCD_WR_REG(0x61);
    LCD_WR_Byte(0x0A);
    LCD_WR_REG(0x71);
    LCD_WR_Byte(0x0A);
    //V2[5:0]
    LCD_WR_REG(0x6c);
    LCD_WR_Byte(0x35);
    LCD_WR_REG(0x7c);
    LCD_WR_Byte(0x29);
    //V61[5:0]
    LCD_WR_REG(0x62);
    LCD_WR_Byte(0x0F);
    LCD_WR_REG(0x72);
    LCD_WR_Byte(0x0F);
    //V20[6:0]
    LCD_WR_REG(0x68);
    LCD_WR_Byte(0x4f);
    LCD_WR_REG(0x78);
    LCD_WR_Byte(0x45);
    //V43[6:0]
    LCD_WR_REG(0x66);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0x76);
    LCD_WR_Byte(0x33);
    //V4[4:0]
    LCD_WR_REG(0x6b);
    LCD_WR_Byte(0x14);
    LCD_WR_REG(0x7b);
    LCD_WR_Byte(0x14);
    //V59[4:0]
    LCD_WR_REG(0x63);
    LCD_WR_Byte(0x09);
    LCD_WR_REG(0x73);
    LCD_WR_Byte(0x09);
    //V6[4:0]
    LCD_WR_REG(0x6a);
    LCD_WR_Byte(0x13);
    LCD_WR_REG(0x7a);
    LCD_WR_Byte(0x16);
    //V57[4:0]
    LCD_WR_REG(0x64);
    LCD_WR_Byte(0x08);
    LCD_WR_REG(0x74);
    LCD_WR_Byte(0x08);
    LCD_WR_REG(0x69);
    LCD_WR_Byte(0x07);
    LCD_WR_REG(0x79);
    LCD_WR_Byte(0x0d);
    LCD_WR_REG(0x65);
    LCD_WR_Byte(0x05);
    LCD_WR_REG(0x75);
    LCD_WR_Byte(0x05);
    LCD_WR_REG(0x67);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0x77);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0x6f);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x7f);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x50);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x52);
    LCD_WR_Byte(0xd6);
    LCD_WR_REG(0x53);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0x54);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0x55);
    LCD_WR_Byte(0x1b);
    LCD_WR_REG(0x56);
    LCD_WR_Byte(0x1b);
    LCD_WR_REG(0xa0);
    LCD_WR_Byte(0x2a);
    LCD_WR_Byte(0x24);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0xa1);
    LCD_WR_Byte(0x84);
    LCD_WR_REG(0xa2);
    LCD_WR_Byte(0x85);
    LCD_WR_REG(0xa8);
    LCD_WR_Byte(0x34);
    LCD_WR_REG(0xa9);
    LCD_WR_Byte(0x80);
    LCD_WR_REG(0xaa);
    LCD_WR_Byte(0x73);
    LCD_WR_REG(0xAB);
    LCD_WR_Byte(0x03);
    LCD_WR_Byte(0x61);
    LCD_WR_REG(0xAC);
    LCD_WR_Byte(0x03);
    LCD_WR_Byte(0x65);
    LCD_WR_REG(0xAD);
    LCD_WR_Byte(0x03);
    LCD_WR_Byte(0x60);
    LCD_WR_REG(0xAE);
    LCD_WR_Byte(0x03);
    LCD_WR_Byte(0x64);
    LCD_WR_REG(0xB9);
    LCD_WR_Byte(0x82);
    LCD_WR_REG(0xBA);
    LCD_WR_Byte(0x83);
    LCD_WR_REG(0xBB);
    LCD_WR_Byte(0x80);
    LCD_WR_REG(0xBC);
    LCD_WR_Byte(0x81);
    LCD_WR_REG(0xBD);
    LCD_WR_Byte(0x02);
    LCD_WR_REG(0xBE);
    LCD_WR_Byte(0x01);
    LCD_WR_REG(0xBF);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0xC0);
    LCD_WR_Byte(0x03);
    LCD_WR_REG(0xc4);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0xc5);
    LCD_WR_Byte(0x80);
    LCD_WR_REG(0xc6);
    LCD_WR_Byte(0x73);
    LCD_WR_REG(0xc7);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0xC8);
    LCD_WR_Byte(0x33);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0xC9);
    LCD_WR_Byte(0x5b);
    LCD_WR_REG(0xCA);
    LCD_WR_Byte(0x5a);
    LCD_WR_REG(0xCB);
    LCD_WR_Byte(0x5d);
    LCD_WR_REG(0xCC);
    LCD_WR_Byte(0x5c);
    LCD_WR_REG(0xCD);
    LCD_WR_Byte(0x33);
    LCD_WR_Byte(0x33);
    LCD_WR_REG(0xCE);
    LCD_WR_Byte(0x5f);
    LCD_WR_REG(0xCF);
    LCD_WR_Byte(0x5e);
    LCD_WR_REG(0xD0);
    LCD_WR_Byte(0x61);
    LCD_WR_REG(0xD1);
    LCD_WR_Byte(0x60);
    LCD_WR_REG(0xB0);
    LCD_WR_Byte(0x3a);
    LCD_WR_Byte(0x3a);
    LCD_WR_Byte(0x00);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0xB6);
    LCD_WR_Byte(0x32);
    LCD_WR_REG(0xB7);
    LCD_WR_Byte(0x80);
    LCD_WR_REG(0xB8);
    LCD_WR_Byte(0x73);
    LCD_WR_REG(0xe0);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0xe1);
    LCD_WR_Byte(0x03);
    LCD_WR_Byte(0x0f);
    LCD_WR_REG(0xe2);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0xe3);
    LCD_WR_Byte(0x01);
    LCD_WR_REG(0xe4);
    LCD_WR_Byte(0x0e);
    LCD_WR_REG(0xe5);
    LCD_WR_Byte(0x01);
    LCD_WR_REG(0xe6);
    LCD_WR_Byte(0x19);
    LCD_WR_REG(0xe7);
    LCD_WR_Byte(0x10);
    LCD_WR_REG(0xe8);
    LCD_WR_Byte(0x10);
    LCD_WR_REG(0xe9);
    LCD_WR_Byte(0x21);
    LCD_WR_REG(0xea);
    LCD_WR_Byte(0x12);
    LCD_WR_REG(0xeb);
    LCD_WR_Byte(0xd0);
    LCD_WR_REG(0xec);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0xed);
    LCD_WR_Byte(0x07);
    LCD_WR_REG(0xee);
    LCD_WR_Byte(0x07);
    LCD_WR_REG(0xef);
    LCD_WR_Byte(0x09);
    LCD_WR_REG(0xF0);
    LCD_WR_Byte(0xD0);
    LCD_WR_REG(0xF1);
    LCD_WR_Byte(0x0E);
    LCD_WR_REG(0xF9);
    LCD_WR_Byte(0x56);
    LCD_WR_REG(0xf2);
    LCD_WR_Byte(0x26);
    LCD_WR_Byte(0x1b);
    LCD_WR_Byte(0x0b);
    LCD_WR_Byte(0x20);
    LCD_WR_REG(0xec);
    LCD_WR_Byte(0x04);
    LCD_WR_REG(0x35);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x44);
    LCD_WR_Byte(0x00);
    LCD_WR_Byte(0x10);
    LCD_WR_REG(0x46);
    LCD_WR_Byte(0x10);
    LCD_WR_REG(0xff);
    LCD_WR_Byte(0x00);
    LCD_WR_REG(0x3a);
    LCD_WR_Byte(0x05);
    LCD_WR_REG(0x36);

#if (USE_HORIZONTIAL == 0)
        LCD_WR_Byte(0x00);
#elif (USE_HORIZONTIAL == 1)
        LCD_WR_Byte(0xC0);
#elif (USE_HORIZONTIAL == 2)
        LCD_WR_Byte(0x70);
 #else
        LCD_WR_Byte(0xA0);
 #endif
    LCD_WR_REG(0x11);
    vTaskDelay(200 / portTICK_PERIOD_MS);
    LCD_WR_REG(0x29);
    vTaskDelay(150 / portTICK_PERIOD_MS);
    return  0;
}

#elif 0
struct nv3007_init_cmd_index
{
    uint8_t reg;
    uint8_t len;
    uint8_t arg[4];
};
const struct nv3007_init_cmd_index cmd_list[] = {
        {0xff, 1, {0xa5}},
        {0x9a, 1, {0x08}},
        {0x9b, 1, {0x08}},
        {0x9c, 1, {0xb0}},
        {0x9d, 1, {0x17}},
        {0x9e, 1, {0xc2}},
        {0x8f, 2, {0x22, 0x04}},
        {0x84, 1, {0x90}},
        {0x83, 1, {0x7b}},
        {0x85, 1, {0x4f}},
        //GAMMA VO[3:0]
        {0x6e, 1, {0x0f}},
        {0x7e, 1, {0x0f}},
        //V63[3:0]
        {0x60, 1, {0x00}},
        {0x70, 1, {0x00}},
        //V1
        {0x6d, 1, {0x39}},
        {0x7d, 1, {0x31}},
        //V62
        {0x61, 1, {0x0a}},
        {0x71, 1, {0x0a}},
        //V2
        {0x6C, 1, {0x35}},
        {0x7C, 1, {0x29}},
        //V61
        {0x62, 1, {0x0f}},
        {0x72, 1, {0x0f}},
        //v20
        {0x68, 1, {0x4f}},
        {0x78, 1, {0x45}},
        //v43
        {0x66, 1, {0x33}},
        {0x76, 1, {0x33}},
        //v4
        {0x6b, 1, {0x14}},
        {0x7b, 1, {0x14}},
        //v59
        {0x63, 1, {0x09}},
        {0x73, 1, {0x09}},
        //v6
        {0x6a, 1, {0x13}},
        {0x7a, 1, {0x16}},
        //v57
        {0x64, 1, {0x08}},
        {0x74, 1, {0x08}},
        {0x69, 1, {0x07}},
        {0x79, 1, {0x0d}},
        {0x65, 1, {0x05}},
        {0x75, 1, {0x05}},
        {0x67, 1, {0x33}},
        {0x77, 1, {0x33}},
        {0x6f, 1, {0x00}},
        {0x7f, 1, {0x00}},
        {0x50, 1, {0x00}},
        {0x52, 1, {0xd6}},
        {0x53, 1, {0x04}},
        {0x54, 1, {0x04}},
        {0x55, 1, {0x1b}},
        {0x56, 1, {0x1b}},
        {0xa0, 3, {0x2a,0x24,0x00}},
        {0xa1, 1, {0x84}},
        {0xa2, 1, {0x85}},
        {0xa8, 1, {0x34}},
        {0xa9, 1, {0x80}},
        {0xaa, 1, {0x73}},
        {0xab, 2, {0x03, 0x61}},
        {0xac, 2, {0x03, 0x65}},
        {0xad, 2, {0x03, 0x60}},
        {0xae, 2, {0x03, 0x64}},
        {0xb9, 1, {0x82}},
        {0xba, 1, {0x83}},
        {0xbb, 1, {0x80}},
        {0xbc, 1, {0x81}},
        {0xbd, 1, {0x02}},
        {0xbe, 1, {0x01}},
        {0xbf, 1, {0x04}},
        {0xc0, 1, {0x03}},
        {0xc4, 1, {0x33}},
        {0xc5, 1, {0x80}},
        {0xc6, 1, {0x73}},
        {0xc7, 1, {0x00}},
        {0xc8, 2, {0x33,0x33}},
        {0xc9, 1, {0x5b}},
        {0xca, 1, {0x5a}},
        {0xcb, 1, {0x5d}},
        {0xcc, 1, {0x5c}},
        {0xcd, 2, {0x33,0x33}},
        {0xce, 1, {0x5f}},
        {0xcf, 1, {0x5e}},
        {0xd0, 1, {0x61}},
        {0xd1, 1, {0x60}},
        {0xb0, 4, {0x3a,0x3a,0x00, 0x00}},
        {0xb6, 1, {0x32}},
        {0xb7, 1, {0x80}},
        {0xb8, 1, {0x73}},
        {0xe0, 1, {0x00}},
        {0xe1, 2, {0x03,0x0f}},
        {0xe2, 1, {0x04}},
        {0xe3, 1, {0x01}},
        {0xe4, 1, {0x0e}},
        {0xe5, 1, {0x01}},
        {0xe6, 1, {0x19}},
        {0xe7, 1, {0x10}},
        {0xe8, 1, {0x10}},
        {0xe9, 1, {0x21}},
        {0xea, 1, {0x12}},
        {0xeb, 1, {0xd0}},
        {0xec, 1, {0x04}},
        {0xed, 1, {0x07}},
        {0xee, 1, {0x07}},
        {0xef, 1, {0x09}},
        {0xf0, 1, {0xd0}},
        {0xf1, 1, {0x0e}},
        {0xf9, 1, {0x56}},
        {0xf2, 4, {0x26,0x1b,0x0b, 0x20}},
        {0xec, 1, {0x04}},
        {0x35, 1, {0x00}},
        {0x44, 2, {0x00, 0x10}},
        {0x46, 1, {0x10}},
        {0xff, 1, {0x00}},
        {0x3a, 1, {0x05}},
#if USE_HORIZONTIAL == 0
        {0x36, 1, {0x00}},
#elif USE_HORIZONTIAL == 1
        {0x36, 1, {0xC0}},
#elif USE_HORIZONTIAL == 2
        {0x36, 1, {0x70}},
#else
        {0x36, 1, {0xA0}},
#endif
};


void spi_send_cmd_index(const struct nv3007_init_cmd_index *index)
{
    LCD_DC_Clr();
    bsp_spi_write_byte( index->reg);
    LCD_DC_Set();
    bsp_spi_write_data(index->arg, index->len);
}

void LCD_Init(void)
{
    lcd_led_init();
    lcd_basic_io_init();
    /* 初始化SPI总线 */
    lcd_spi_init(LCD_SPI_HANDLE_USE, LCD_MAX_BUF_SIZE);

    LCD_RES_Set();
    vTaskDelay(50 / portTICK_PERIOD_MS);
    LCD_RES_Clr();
    vTaskDelay(50 / portTICK_PERIOD_MS);
    LCD_RES_Set();
    vTaskDelay(120 / portTICK_PERIOD_MS);

    LCD_WR_REG(0x11);
    vTaskDelay(120 / portTICK_PERIOD_MS);

#define array_size(x) (sizeof(x)/sizeof(x[0]))

    for (int i = 0; i < array_size(cmd_list); ++i) {
        spi_send_cmd_index( &cmd_list[i]);
    }

    LCD_WR_REG(0x11);
    vTaskDelay(200 / portTICK_PERIOD_MS);
    LCD_WR_REG(0x29);
    vTaskDelay(150 / portTICK_PERIOD_MS);

    lcd_set_backlight(1);
}
#else
// 结构体定义（柔性数组）
struct nv3007_init_cmd {
    uint8_t reg;
    uint8_t len;
    uint8_t arg[]; // 柔性数组
};

// 动态创建命令的函数
struct nv3007_init_cmd* nv3007_create_cmd(uint8_t reg, uint8_t len, const uint8_t* args) {
    struct nv3007_init_cmd* cmd = malloc(sizeof(struct nv3007_init_cmd) + len);
    if (cmd) {
        cmd->reg = reg;
        cmd->len = len;
        memcpy(cmd->arg, args, len);
    }
    return cmd;
}

// 完整的命令列表初始化函数
struct nv3007_init_cmd** nv3007_init_commands(void) {
    // 分配指针数组（ NULL结尾）
    struct nv3007_init_cmd** cmd_list = malloc(sizeof(struct nv3007_init_cmd*) * 120);
    if (!cmd_list) return NULL;
    // 初始化所有命令（按原始顺序）
    int i = 0;
    cmd_list[i++] = nv3007_create_cmd(0xff, 1, (uint8_t[]) { 0xa5 });
    cmd_list[i++] = nv3007_create_cmd(0x9a, 1, (uint8_t[]) { 0x08 });
    cmd_list[i++] = nv3007_create_cmd(0x9b, 1, (uint8_t[]) { 0x08 });
    cmd_list[i++] = nv3007_create_cmd(0x9c, 1, (uint8_t[]) { 0xb0 });
    cmd_list[i++] = nv3007_create_cmd(0x9d, 1, (uint8_t[]) { 0x17 });
    cmd_list[i++] = nv3007_create_cmd(0x9e, 1, (uint8_t[]) { 0xc2 });
    cmd_list[i++] = nv3007_create_cmd(0x8f, 2, (uint8_t[]) { 0x22, 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0x84, 1, (uint8_t[]) { 0x90 });
    cmd_list[i++] = nv3007_create_cmd(0x83, 1, (uint8_t[]) { 0x7b });
    cmd_list[i++] = nv3007_create_cmd(0x85, 1, (uint8_t[]) { 0x4f });
    cmd_list[i++] = nv3007_create_cmd(0x6e, 1, (uint8_t[]) { 0x0f });
    cmd_list[i++] = nv3007_create_cmd(0x7e, 1, (uint8_t[]) { 0x0f });
    cmd_list[i++] = nv3007_create_cmd(0x60, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x70, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x6d, 1, (uint8_t[]) { 0x39 });
    cmd_list[i++] = nv3007_create_cmd(0x7d, 1, (uint8_t[]) { 0x31 });
    cmd_list[i++] = nv3007_create_cmd(0x61, 1, (uint8_t[]) { 0x0a });
    cmd_list[i++] = nv3007_create_cmd(0x71, 1, (uint8_t[]) { 0x0a });
    cmd_list[i++] = nv3007_create_cmd(0x6C, 1, (uint8_t[]) { 0x35 });
    cmd_list[i++] = nv3007_create_cmd(0x7C, 1, (uint8_t[]) { 0x29 });
    cmd_list[i++] = nv3007_create_cmd(0x62, 1, (uint8_t[]) { 0x0f });
    cmd_list[i++] = nv3007_create_cmd(0x72, 1, (uint8_t[]) { 0x0f });
    cmd_list[i++] = nv3007_create_cmd(0x68, 1, (uint8_t[]) { 0x4f });
    cmd_list[i++] = nv3007_create_cmd(0x78, 1, (uint8_t[]) { 0x45 });
    cmd_list[i++] = nv3007_create_cmd(0x66, 1, (uint8_t[]) { 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0x76, 1, (uint8_t[]) { 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0x6b, 1, (uint8_t[]) { 0x14 });
    cmd_list[i++] = nv3007_create_cmd(0x7b, 1, (uint8_t[]) { 0x14 });
    cmd_list[i++] = nv3007_create_cmd(0x63, 1, (uint8_t[]) { 0x09 });
    cmd_list[i++] = nv3007_create_cmd(0x73, 1, (uint8_t[]) { 0x09 });
    cmd_list[i++] = nv3007_create_cmd(0x6a, 1, (uint8_t[]) { 0x13 });
    cmd_list[i++] = nv3007_create_cmd(0x7a, 1, (uint8_t[]) { 0x16 });
    cmd_list[i++] = nv3007_create_cmd(0x64, 1, (uint8_t[]) { 0x08 });
    cmd_list[i++] = nv3007_create_cmd(0x74, 1, (uint8_t[]) { 0x08 });
    cmd_list[i++] = nv3007_create_cmd(0x69, 1, (uint8_t[]) { 0x07 });
    cmd_list[i++] = nv3007_create_cmd(0x79, 1, (uint8_t[]) { 0x0d });
    cmd_list[i++] = nv3007_create_cmd(0x65, 1, (uint8_t[]) { 0x05 });
    cmd_list[i++] = nv3007_create_cmd(0x75, 1, (uint8_t[]) { 0x05 });
    cmd_list[i++] = nv3007_create_cmd(0x67, 1, (uint8_t[]) { 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0x77, 1, (uint8_t[]) { 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0x6f, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x7f, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x50, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x52, 1, (uint8_t[]) { 0xd6 });
    cmd_list[i++] = nv3007_create_cmd(0x53, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0x54, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0x55, 1, (uint8_t[]) { 0x1b });
    cmd_list[i++] = nv3007_create_cmd(0x56, 1, (uint8_t[]) { 0x1b });
    cmd_list[i++] = nv3007_create_cmd(0xa0, 3, (uint8_t[]) { 0x2a, 0x24, 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0xa1, 1, (uint8_t[]) { 0x84 });
    cmd_list[i++] = nv3007_create_cmd(0xa2, 1, (uint8_t[]) { 0x85 });
    cmd_list[i++] = nv3007_create_cmd(0xa8, 1, (uint8_t[]) { 0x34 });
    cmd_list[i++] = nv3007_create_cmd(0xa9, 1, (uint8_t[]) { 0x80 });
    cmd_list[i++] = nv3007_create_cmd(0xaa, 1, (uint8_t[]) { 0x73 });
    cmd_list[i++] = nv3007_create_cmd(0xab, 2, (uint8_t[]) { 0x03, 0x61 });
    cmd_list[i++] = nv3007_create_cmd(0xac, 2, (uint8_t[]) { 0x03, 0x65 });
    cmd_list[i++] = nv3007_create_cmd(0xad, 2, (uint8_t[]) { 0x03, 0x60 });
    cmd_list[i++] = nv3007_create_cmd(0xae, 2, (uint8_t[]) { 0x03, 0x64 });
    cmd_list[i++] = nv3007_create_cmd(0xb9, 1, (uint8_t[]) { 0x82 });
    cmd_list[i++] = nv3007_create_cmd(0xba, 1, (uint8_t[]) { 0x83 });
    cmd_list[i++] = nv3007_create_cmd(0xbb, 1, (uint8_t[]) { 0x80 });
    cmd_list[i++] = nv3007_create_cmd(0xbc, 1, (uint8_t[]) { 0x81 });
    cmd_list[i++] = nv3007_create_cmd(0xbd, 1, (uint8_t[]) { 0x02 });
    cmd_list[i++] = nv3007_create_cmd(0xbe, 1, (uint8_t[]) { 0x01 });
    cmd_list[i++] = nv3007_create_cmd(0xbf, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0xc0, 1, (uint8_t[]) { 0x03 });
    cmd_list[i++] = nv3007_create_cmd(0xc4, 1, (uint8_t[]) { 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0xc5, 1, (uint8_t[]) { 0x80 });
    cmd_list[i++] = nv3007_create_cmd(0xc6, 1, (uint8_t[]) { 0x73 });
    cmd_list[i++] = nv3007_create_cmd(0xc7, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0xc8, 2, (uint8_t[]) { 0x33, 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0xc9, 1, (uint8_t[]) { 0x5b });
    cmd_list[i++] = nv3007_create_cmd(0xca, 1, (uint8_t[]) { 0x5a });
    cmd_list[i++] = nv3007_create_cmd(0xcb, 1, (uint8_t[]) { 0x5d });
    cmd_list[i++] = nv3007_create_cmd(0xcc, 1, (uint8_t[]) { 0x5c });
    cmd_list[i++] = nv3007_create_cmd(0xcd, 2, (uint8_t[]) { 0x33, 0x33 });
    cmd_list[i++] = nv3007_create_cmd(0xce, 1, (uint8_t[]) { 0x5f });
    cmd_list[i++] = nv3007_create_cmd(0xcf, 1, (uint8_t[]) { 0x5e });
    cmd_list[i++] = nv3007_create_cmd(0xd0, 1, (uint8_t[]) { 0x61 });
    cmd_list[i++] = nv3007_create_cmd(0xd1, 1, (uint8_t[]) { 0x60 });
    cmd_list[i++] = nv3007_create_cmd(0xb0, 4, (uint8_t[]) { 0x3a, 0x3a, 0x00, 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0xb6, 1, (uint8_t[]) { 0x32 });
    cmd_list[i++] = nv3007_create_cmd(0xb7, 1, (uint8_t[]) { 0x80 });
    cmd_list[i++] = nv3007_create_cmd(0xb8, 1, (uint8_t[]) { 0x73 });
    cmd_list[i++] = nv3007_create_cmd(0xe0, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0xe1, 2, (uint8_t[]) { 0x03, 0x0f });
    cmd_list[i++] = nv3007_create_cmd(0xe2, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0xe3, 1, (uint8_t[]) { 0x01 });
    cmd_list[i++] = nv3007_create_cmd(0xe4, 1, (uint8_t[]) { 0x0e });
    cmd_list[i++] = nv3007_create_cmd(0xe5, 1, (uint8_t[]) { 0x01 });
    cmd_list[i++] = nv3007_create_cmd(0xe6, 1, (uint8_t[]) { 0x19 });
    cmd_list[i++] = nv3007_create_cmd(0xe7, 1, (uint8_t[]) { 0x10 });
    cmd_list[i++] = nv3007_create_cmd(0xe8, 1, (uint8_t[]) { 0x10 });
    cmd_list[i++] = nv3007_create_cmd(0xe9, 1, (uint8_t[]) { 0x21 });
    cmd_list[i++] = nv3007_create_cmd(0xea, 1, (uint8_t[]) { 0x12 });
    cmd_list[i++] = nv3007_create_cmd(0xeb, 1, (uint8_t[]) { 0xd0 });
    cmd_list[i++] = nv3007_create_cmd(0xec, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0xed, 1, (uint8_t[]) { 0x07 });
    cmd_list[i++] = nv3007_create_cmd(0xee, 1, (uint8_t[]) { 0x07 });
    cmd_list[i++] = nv3007_create_cmd(0xef, 1, (uint8_t[]) { 0x09 });
    cmd_list[i++] = nv3007_create_cmd(0xf0, 1, (uint8_t[]) { 0xd0 });
    cmd_list[i++] = nv3007_create_cmd(0xf1, 1, (uint8_t[]) { 0x0e });
    cmd_list[i++] = nv3007_create_cmd(0xf9, 1, (uint8_t[]) { 0x56 });
    cmd_list[i++] = nv3007_create_cmd(0xf2, 4, (uint8_t[]) { 0x26, 0x1b, 0x0b, 0x20 });
    cmd_list[i++] = nv3007_create_cmd(0xec, 1, (uint8_t[]) { 0x04 });
    cmd_list[i++] = nv3007_create_cmd(0x35, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x44, 2, (uint8_t[]) { 0x00, 0x10 });
    cmd_list[i++] = nv3007_create_cmd(0x46, 1, (uint8_t[]) { 0x10 });
    cmd_list[i++] = nv3007_create_cmd(0xff, 1, (uint8_t[]) { 0x00 });
    cmd_list[i++] = nv3007_create_cmd(0x3a, 1, (uint8_t[]) { 0x05 });
#if USE_HORIZONTIAL == 0
    cmd_list[i++] = nv3007_create_cmd(0x36, 1, (uint8_t[]) { 0x00 });
#elif USE_HORIZONTIAL == 1
    cmd_list[i++] = nv3007_create_cmd(0x36, 1, (uint8_t[]) { 0xC0 });
#elif USE_HORIZONTIAL == 2
    cmd_list[i++] = nv3007_create_cmd(0x36, 1, (uint8_t[]) { 0x70 });
#else
    cmd_list[i++] = nv3007_create_cmd(0x36, 1, (uint8_t[]) { 0xA0 });
#endif
    // NULL结尾
    cmd_list[i] = NULL;
    return cmd_list;
}
// 释放命令列表的函数
void nv3007_free_commands(struct nv3007_init_cmd** cmd_list) {
    for (int i = 0; cmd_list[i] != NULL; i++) {
        free(cmd_list[i]);
    }
    free(cmd_list);
}



int lcd_init(int lcd_w, int lcd_h)
{
    lcd_basic_io_init();
    /* 初始化SPI总线 */
    lcd_spi_init(LCD_SPI_HANDLE_USE, lcd_w*lcd_h*2);

    lcd_set_rst(1);
    vTaskDelay(50 / portTICK_PERIOD_MS);
    lcd_set_rst(0);
    vTaskDelay(50 / portTICK_PERIOD_MS);
    lcd_set_rst(1);
    vTaskDelay(120 / portTICK_PERIOD_MS);

    LCD_WR_REG(0x11);
    vTaskDelay(120 / portTICK_PERIOD_MS);

    struct nv3007_init_cmd** cmd_list = nv3007_init_commands();
    if (!cmd_list) {
        return -1;
    }
    for (int i = 0; cmd_list[i] != NULL; i++) {
        // 实际调用SPI发送函数：
        spi_send_cmd(cmd_list[i]->reg, cmd_list[i]->len, cmd_list[i]->arg);
    }
    nv3007_free_commands(cmd_list);

    LCD_WR_REG(0x11);
    vTaskDelay(200 / portTICK_PERIOD_MS);

    LCD_WR_REG(0x29);
    vTaskDelay(150 / portTICK_PERIOD_MS);

    lcd_set_backlight(1);
    return 0;
}

#endif
